package com.superhelper.app.service;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.superhelper.app.common.Consts;
import com.superhelper.app.domain.AccessToken;
import com.superhelper.app.domain.AuserShopAudio;
import com.superhelper.app.domain.RespShop;
import com.superhelper.app.mapper.AdminMapper;
import com.superhelper.common.domain.AuserDeliver;
import com.superhelper.common.domain.AuserShop;
import com.superhelper.common.domain.DeliverAccount;
import com.superhelper.common.domain.TakeOutShopInfo;
import com.superhelper.common.service.BaiduService;
import com.superhelper.common.service.RedisService;
import com.superhelper.common.utils.CoodinateCovertor;
import com.superhelper.common.utils.CoodinateCovertor.Coordinate;
import com.superhelper.common.utils.JsonHelper;
import com.superhelper.common.utils.ThreadPool;

import eleme.openapi.sdk.oauth.response.Token;

@Service
public class ShopService {
    protected Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private ElemeService elemeService;
    @Autowired
    private ThreadPool threadPool;
    @Autowired
    private MtService mtService;
    @Autowired
    private BaiduService baiduService;

    @Autowired
    private DeliverService deliverService;

    public String getAuthUrl(Integer auserId, String type) throws UnsupportedEncodingException {
        if (type.equals(AuserShop.SHOP_ELEME)) {
            return elemeService.getAuthUrl(auserId);
        } else if (type.equals(AuserShop.SHOP_MEITUAN)) {
            String ePoiId = +System.currentTimeMillis() + String.valueOf(auserId);
            List<AuserShop> shops = adminMapper.getAuserShopsByAuserId(Long.valueOf(auserId));
            for (AuserShop s : shops) {
                if (s.getShop_type().equals(AuserShop.SHOP_MEITUAN)) {
                    ePoiId = s.getShopId();
                    break;
                }
            }
            return mtService.getAuthUrl(auserId, ePoiId);
        } else {
            // return baiduService.getAuthUrl(auserId);
            return null;
        }
    }

    public boolean elemeAuthCallBack(Integer auserId, String code) {
        try {
            // 根据OAuth2.0中的对应state，scope和callback_url，获取授权URL
            Token token = elemeService.getTokenByCode(code);
            log.info("[checkAuthCallBack]token:{}", JsonHelper.toJson(token));
            if (!token.isSuccess()) {
                log.error("[checkAuthCallBack]token error:{}", auserId);
                return false;
            }

            final AccessToken accessToken = new AccessToken();
            accessToken.setExpires(token.getExpires());
            accessToken.setRefreshToken(token.getRefreshToken());
            accessToken.setTokenType(token.getTokenType());
            accessToken.setToken(token.getAccessToken());
            accessToken.setTokenAt(new Date());
            String shopId = elemeService.getShopId(token);
            accessToken.setShopId(shopId);

            AuserShop shop = adminMapper.getAuserShopByType(shopId, AuserShop.SHOP_ELEME);
            if (shop == null) {// 没绑定过
                shop = new AuserShop();
                shop.setToken(JsonHelper.toJson(accessToken));
                shop.setAuserId(auserId);
                shop.setShopId(shopId);
                shop.setShop_type(AuserShop.SHOP_ELEME);
                shop.setState(1);
                int res = adminMapper.addAuserShop(shop);
                log.info("[checkAuthCallBack]res:{}", res);
            } else {

                adminMapper.updateShopToken(auserId, shopId, AuserShop.SHOP_ELEME, JsonHelper.toJson(accessToken));
            }
            String token_key = Consts.Cache.ELEME_TOKEN + shopId;
            redisService.set(token_key, accessToken);

            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        TakeOutShopInfo shop = getShopInfo(accessToken.getShopId(), AuserShop.SHOP_ELEME);
                        adminMapper.updateShopPoi(accessToken.getShopId(), AuserShop.SHOP_ELEME, shop.getLatitude(),
                                shop.getLongitude(), shop.getPartnerId());
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        log.error("", e);
                    }
                }
            });

            log.info("[checkAuthCallBack]shop:{}", JsonHelper.toJson(shop));
            return true;
        } catch (Exception e) {
            log.error("[checkAuthCallBack]error:{}", e);
            return false;
        }
    }

    public TakeOutShopInfo getShopInfo(String shopId, String type) throws Exception {
        String key = Consts.Cache.SUPER_SHOP + type + shopId;
        TakeOutShopInfo shop = redisService.get(key, TakeOutShopInfo.class);
        if (shop == null) {
            if (AuserShop.SHOP_ELEME.equals(type)) {
                shop = elemeService.getShopInfo(shopId);
            } else if (AuserShop.SHOP_MEITUAN.equals(type)) {
                shop = mtService.getShopInfo(shopId);
            } else if (AuserShop.SHOP_BAIDU.equals(type)) {
                AuserShop ashop = adminMapper.getAuserShopByType(shopId, AuserShop.SHOP_BAIDU);
                shop = baiduService.getShop(ashop.getSource(), shopId);
                if (StringUtils.isBlank(ashop.getPartnerId())) {// 兼容旧数据，新增合作商户ID
                    adminMapper.updateShopPoi(shopId, ashop.getShop_type(), ashop.getLat(), ashop.getLon(),
                            shop.getPartnerId());
                }
            }
            if (shop != null) {
                redisService.set(key, 600, shop);
            }
        }
        return shop;
    }

    public List<RespShop> getValidAuserShopsByAuserId(Long auserId) throws Exception {
        List<RespShop> result = new ArrayList<RespShop>();
        List<AuserShop> shops = adminMapper.getAuserShopsByAuserId(auserId);
        AuserDeliver deliver = deliverService.getAuserDeliver(auserId);
        for (AuserShop s : shops) {
            if (s.getState() == 1) {
                try {
                    TakeOutShopInfo info = this.getShopInfo(s.getShopId(), s.getShop_type());
                    RespShop rs = new RespShop();
                    BeanUtils.copyProperties(s, rs);
                    if (deliver != null) {
                        rs.setDeliverAuto(deliver.getState());
                    }
                    if (info != null) {
                        rs.setIsOpen(info.getIsOpen() == 1);
                        result.add(rs);
                    }
                } catch (Exception e) {
                    log.error("", e);
                }
            }
        }
        return result;
    }

    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    public int updateConf(List<RespShop> shops, Long auserId) throws Exception {
        List<AuserShop> list = adminMapper.getAuserShopsByAuserId(auserId);
        for (RespShop s : shops) {
            for (AuserShop shop : list) {
                if (shop.getId().equals(s.getId())) {
                    // 手动发单
                    if (s.getDeliverType() == 2) {
                        if (s.getDeliverType() != shop.getDeliverType() && s.getContinueType() == 1) {// 清除等待发单队列
                            deliverService.deleteTaskByStopAuto(shop.getShop_type(), shop.getShopId());
                        }
                    }
                    shop.setId(s.getId());
                    shop.setOrderAuto(s.getOrderAuto());
                    shop.setDeliverType(s.getDeliverType());
                    int deliverType = 0;
                    if (shop.getDeliverType() == 1 || shop.getDeliverType() == 2) {
                        deliverType = 1;// 达达
                    }
                    DeliverAccount account = deliverService.getDeliverAccountByType((long) shop.getAuserId(),
                            deliverType);
                    if (account != null) {
                        shop.setDeliverUid(account.getDeliverUid());
                        shop.setDeliverShopNo(account.getDeliverShopNo());
                    }
                    if (shop.getShop_type().equals(AuserShop.SHOP_ELEME)) {
                        int state = s.getIsOpen() ? 1 : 0;
                        elemeService.openShop(shop.getShopId(), state);
                    } else if (shop.getShop_type().equals(AuserShop.SHOP_MEITUAN)) {
                        int state = s.getIsOpen() ? 1 : 0;
                        mtService.mtOpen(shop.getShopId(), state);
                    } else if (shop.getShop_type().equals(AuserShop.SHOP_BAIDU)) {
                        int state = s.getIsOpen() ? 1 : 0;
                        baiduService.shopStatus(shop.getSource(), shop.getShopId(), state);
                    }
                    adminMapper.updateOrderConf(shop);
                    String key = Consts.Cache.SUPER_SHOP + shop.getShop_type() + shop.getShopId();
                    redisService.delKey(key);
                    break;
                }
            }
        }
        return shops.size();
    }

    public int updateDeliverSwitch(Long id, int deliverType) {
        return adminMapper.updateDeliverSwitch(id, deliverType);
    }

    public AuserShop getAuserShop(String shopId, String shop_type) {
        return adminMapper.getAuserShopByType(shopId, shop_type);
    }

    public boolean mtAuthCallBack(Integer auserId, String shopId, String token) {
        try {
            if (StringUtils.isBlank(token)) {
                log.error("[checkAuthCallBack]token error:{}", auserId);
                return false;
            }
            final AccessToken accessToken = new AccessToken();
            Long expires = System.currentTimeMillis();
            accessToken.setExpires(expires);
            accessToken.setRefreshToken(token);
            accessToken.setTokenType("mt");
            accessToken.setToken(token);
            accessToken.setTokenAt(new Date());
            accessToken.setShopId(shopId);

            AuserShop shop = adminMapper.getAuserShopByType(shopId, AuserShop.SHOP_MEITUAN);
            if (shop == null) {// 没绑定过
                shop = new AuserShop();
                shop.setToken(JsonHelper.toJson(accessToken));
                shop.setAuserId(auserId);
                shop.setShopId(shopId);
                shop.setShop_type(AuserShop.SHOP_MEITUAN);
                shop.setState(1);
                int res = adminMapper.addAuserShop(shop);
                log.info("[checkAuthCallBack]res:{}", res);
            } else {
                adminMapper.updateShopToken(auserId, shopId, AuserShop.SHOP_MEITUAN, JsonHelper.toJson(accessToken));
            }
            String token_key = Consts.Cache.MT_TOKEN + shopId;
            redisService.set(token_key, accessToken);

            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        TakeOutShopInfo shop = getShopInfo(accessToken.getShopId(), AuserShop.SHOP_MEITUAN);
                        adminMapper.updateShopPoi(accessToken.getShopId(), AuserShop.SHOP_MEITUAN, shop.getLatitude(),
                                shop.getLongitude(), shop.getPartnerId());
                    } catch (Exception e) {
                        log.error("", e);
                    }

                }
            });

            log.info("[checkAuthCallBack]shop:{}", JsonHelper.toJson(shop));
            return true;
        } catch (Exception e) {
            log.error("[checkAuthCallBack]error:{}", e);
            return false;
        }
    }

    public List<AuserShopAudio> getAuserAudioByAuserId(Long auserId) {
        List<AuserShopAudio> baseList = adminMapper.getAuserAudioByAuserId(0l);
        List<AuserShopAudio> audios = adminMapper.getAuserAudioByAuserId(auserId);
        if (!audios.isEmpty()) {
            for (AuserShopAudio a : audios) {
                for (AuserShopAudio b : baseList) {
                    if (b.getType().equals(a.getType())) {
                        b.setCount(a.getCount());
                    }
                }
            }
        }
        return baseList;
    }

    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    public int saveAudio(List<AuserShopAudio> list) {
        List<AuserShopAudio> baseList = adminMapper.getAuserAudioByAuserId(0l);
        for (AuserShopAudio a : list) {
            for (AuserShopAudio b : baseList) {
                if (b.getId().equals(a.getId())) {
                    b.setAuserId(a.getAuserId());
                    b.setCount(a.getCount());
                    adminMapper.addAudio(b);
                    break;
                }
            }
        }
        return list.size();
    }

    public boolean openShop(Long id, Integer state) throws Exception {
        boolean result = false;
        AuserShop shop = adminMapper.getAuserShopById(id);
        String type = shop.getShop_type();
        String shopId = shop.getShopId();
        String key = Consts.Cache.SUPER_SHOP + type + shopId;
        if (AuserShop.SHOP_ELEME.equals(type)) {
            result = elemeService.openShop(shopId, state);
        } else if (AuserShop.SHOP_MEITUAN.equals(type)) {
            result = mtService.mtOpen(shopId, state);
        } else if (AuserShop.SHOP_BAIDU.equals(type)) {
            result = baiduService.shopStatus(shop.getSource(), shopId, state);
        }
        redisService.delKey(key);
        return result;
    }

    public int bdBound(Integer auserId, String source, final String shopId) {

        TakeOutShopInfo entity = baiduService.getShop(source, shopId);
        if (entity == null) {
            return -1;
        }
        AuserShop shop = adminMapper.getAuserShopByType(shopId, AuserShop.SHOP_BAIDU);
        int res = 0;
        if (shop == null) {
            shop = new AuserShop();
            shop.setToken("{}");
            shop.setAuserId(auserId);
            shop.setShopId(shopId);
            shop.setSource(source);
            shop.setShop_type(AuserShop.SHOP_BAIDU);
            shop.setState(1);
            res = adminMapper.addAuserShop(shop);
        } else {
            res = adminMapper.updateShopToken(auserId, shopId, AuserShop.SHOP_BAIDU, shop.getToken());
        }
        if (res > 0) {
            threadPool.submit(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        TakeOutShopInfo shop = getShopInfo(shopId, AuserShop.SHOP_BAIDU);
                        Coordinate c = new Coordinate(shop.getLongitude(), shop.getLatitude());
                        CoodinateCovertor.fromBd(c);
                        adminMapper.updateShopPoi(shopId, AuserShop.SHOP_BAIDU, c.getLantitude(), c.getLongitude(),
                                shop.getPartnerId());
                    } catch (Exception e) {
                        // TODO Auto-generated catch block
                        log.error("", e);
                    }
                }
            });
        }
        return res;
    }
}
